#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/types.h>
#include <pthread.h>
#define NUM_CUSTOMERS 30
#define ROOM_CAPACITY 10


sem_t cust_room,barber;
pthread_key_t key;
sigset_t sigset;


#define NUM_THREADS     50
#define ROOMCAPACITY     10

pthread_mutex_t hairCutSession = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t barberChair = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t BarberChairM = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t BarberChairC = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t waitingChairM = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t roomM = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_cond  = PTHREAD_COND_INITIALIZER;


int waiting_chair_seats = 0;
int customersInRoom = 0;

int customerCount = 20;
pthread_t threads[NUM_THREADS];

void mypc_produce()
{

printf("[barber] : Anyone wants hair cut?\n");
pthread_cond_signal( &condition_cond );

}


void mypc_consume(long tid)
{
pthread_mutex_lock( &BarberChairC );
//printf("[customer - %ld] : Where is this fucking barber.\n", tid);
pthread_cond_wait( &condition_cond, &BarberChairC );
printf("[customer - %ld] : I am getting hair cut.\n", tid);

customerCount --;


pthread_mutex_lock( &roomM );
customersInRoom--;
pthread_mutex_unlock( &roomM );
printf("[Customer - %ld ] Leaves Barber shop [ %d ]\n------------------------------------------\n",tid, waiting_chair_seats);


pthread_mutex_unlock( &BarberChairM );
pthread_mutex_unlock( &BarberChairC );
}


void *barber_thread(void *arg)
{
	   long tid;
	   tid = (long)arg;

	   printf("[Barber]: opens the shop\n------------------------------------------\n",tid);


	   while(customerCount>0)
	   {
		   sleep(1);
		   pthread_mutex_lock( &BarberChairM );
		   printf("[Barber]: Customers Remaining = %d\n",customerCount);
		   printf("[Barber]: customer_in_room = %d\n",customersInRoom);
		   printf("[Barber]: ready_customer = %d\n",waiting_chair_seats);
		   mypc_produce();

	   }

	   printf("[Barber]: No one? okay i will close this shop\n------------------------------------------\n",tid);


}


void *customer_thread(void *arg)
 {

    long tid;
	   tid = (long)arg;

	   while(1){
		   pthread_mutex_lock( &roomM );
		   if(customersInRoom < 10)
			   {
			   customersInRoom++;
			   printf("[Customer - %ld ] I am inside the room  [ %d ]\n",tid,customersInRoom);
			   pthread_mutex_unlock( &roomM );
			   break;
			   }
		   pthread_mutex_unlock( &roomM );
	   }


    mypc_consume(tid);

 }


void handler()
{

//handler

}


int main()
{

		int i,rc;
		long t=0; void *status;
		pthread_attr_t attr;
		/* Initialize and set thread detached attribute */
	   pthread_attr_init(&attr);
	   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

	   for(i=1;i<=20;i++)
	   {
		 t=i;
	      rc = pthread_create(&threads[i], &attr, customer_thread, (void *)t);
	      if (rc){
	         printf("ERROR; return code from pthread_create() is %d\n", rc);
	         exit(-1);
	      }
	   }

	   rc = pthread_create(&threads[0], &attr, barber_thread, (void *)t);
	   	      if (rc){
	   	         printf("ERROR; return code from pthread_create() is %d\n", rc);
	   	         exit(-1);
	   	      }


	      rc = pthread_join(threads[0], &status);
		      if (rc) {
		         printf("ERROR; return code from pthread_join() is %d\n", rc);
		         exit(-1);
	         }

}



